<?php
	class SitemapGenerator {
		public $namaFileSitemap = 'sitemap.xml';
		public $namaFileRobot = 'robots.txt';
		public $totalMaksimumUrl = 25000;
		public $buatKompresiFile = false;
		public $namaindexSitemap = 'sitemap-index.xml';
		
		private $urlDir;
		private $pathDir;
		private $kirimKeSE = array(array("http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=IDAPPYAHOO&url=","http://search.yahooapis.com/SiteExplorerService/V1/ping?sitemap="),"http://submissions.ask.com/ping?sitemap=","http://www.bing.com/webmaster/ping.aspx?siteMap=","http://www.google.com/webmasters/tools/ping?sitemap=");
		private $dataSitemap;
		private $dataURl;
		private $URlFullSitemap;
		
		public function __construct($urlDir, $pathDir="") {
			$this->urlDir = $urlDir;
			$this->pathDir = $pathDir;
		}
		
		public function addUrl($url, $lastModified = null, $changeFrequency = null, $priority = null) {
			if ($url == null)
				throw new Exception("URl mutlak diperlukan.");
			$urlLength = extension_loaded('mbstring') ? mb_strlen($url) : strlen($url);
			if ($urlLength > 2048)
				throw new Exception("panjang karakter URl tidak boleh lebih dari 2048 byte. Pastikan Server anda dapat menggunakan mbstring. Cek dengan phpinfo()");
			$tmp = array();
			$tmp['loc'] = $url;
			if (isset($lastModified)) $tmp['lastmod'] = $lastModified;
			if (isset($changeFrequency)) $tmp['changefreq'] = $changeFrequency;
			if (isset($priority)) $tmp['priority'] = $priority;
			$this->dataURl[] = $tmp;
		}

		public function buatSitemap() {
			if (!isset($this->dataURl))
				throw new Exception("Untuk membuat Sitemap gunakan fungsi addUrl untuk menambah URl.");
			if ($this->totalMaksimumUrl > 50000)
				throw new Exception("Lebih dari 50 ribu URl dalam satu file sitemap tidak diperbolehkan.");
	
			$infoSitemap = '<!-- generator="SitemapGenerator" -->
							  <!-- sitemap-generator-url="http://'.$_SERVER['HTTP_HOST'].'" -->
							  <!-- generated-on="'.date('c').'" -->';
			$sitemapHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>".$infoSitemap."
							  <urlset
							  xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"
							  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
							  xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\">
							  </urlset>";
			$sitemapIndexHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>".$infoSitemap."
									<sitemapindex
										xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
										xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9 
										http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd\" 
										xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">
								  </sitemapindex>";
			foreach(array_chunk($this->dataURl,$this->totalMaksimumUrl) as $sitemap) {
				$xml = new SimpleXMLElement($sitemapHeader);
				foreach($sitemap as $url) {
					$row = $xml->addChild('url');
					$row->addChild('loc',htmlspecialchars($url['loc'],ENT_QUOTES,'UTF-8'));
					if (isset($url['lastmod'])) $row->addChild('lastmod', $url['lastmod']);
					if (isset($url['changefreq'])) $row->addChild('changefreq',$url['changefreq']);
					if (isset($url['priority'])) $row->addChild('priority',$url['priority']);
				}
				if (strlen($xml->asXML()) > 5242880)
					throw new Exception("Ukuran file lebih dari 5MB (5.242.880), Silahkan Kurangi ukuran dari $totalMaksimumUrl.");
				$this->dataSitemap[] = $xml->asXML();
			}
			
			if (sizeof($this->dataSitemap) > 1000)
				throw new Exception("Indeks Sitemap hanya dapat menampung 1000 saja. Silahkan cek Indeks Sitemap anda.");
			if (sizeof($this->dataSitemap) > 1) {
				for($i=0; $i<sizeof($this->dataSitemap); $i++) {
					$this->dataSitemap[$i] = array(str_replace(".xml", ($i+1).".xml.gz", $this->namaFileSitemap),$this->dataSitemap[$i]);
				}
				$xml = new SimpleXMLElement($sitemapIndexHeader);
				foreach($this->dataSitemap as $sitemap) {
					$row = $xml->addChild('sitemap');
					$row->addChild('loc',$this->urlDir.htmlentities($sitemap[0]));
					$row->addChild('lastmod', date('c'));
				}
				$this->URlFullSitemap = $this->urlDir.$this->namaindexSitemap;
				$this->namaindexSitemap = array($this->namaindexSitemap, $xml->asXML());
			} else {
				if ($this->buatKompresiFile)
					$this->URlFullSitemap = $this->urlDir.$this->namaFileSitemap.".gz";
				else
					$this->URlFullSitemap = $this->urlDir.$this->namaFileSitemap;
				$this->dataSitemap[0] = array(
					$this->namaFileSitemap,
					$this->dataSitemap[0]);
				
				$xml = new SimpleXMLElement($sitemapIndexHeader);
				foreach($this->dataSitemap as $sitemap) {
					$row = $xml->addChild('sitemap');
					$row->addChild('loc',$this->urlDir.htmlentities($sitemap[0]));
					$row->addChild('lastmod', date('c'));
				}
				$this->URlFullSitemap = $this->urlDir.$this->namaindexSitemap;
				$this->namaindexSitemap = array($this->namaindexSitemap, $xml->asXML());
			}
		}
		
		private function _tulisFile($content, $filePath, $fileName) {
			$file = fopen($filePath.$fileName, 'w');
			if (!$file) {
				throw new Exception("Tidak dapat menulis Berkas ".$fileName);
			} else {
				fwrite($file, $content);
			}
			return fclose($file);
		}

		private function _tulisGZipFile($content, $filePath, $fileName) {
			$file = gzopen($filePath.$fileName, 'w');
			if (!$file) {
				throw new Exception("Tidak dapat menulis Kompresi Berkas ".$fileName);
			} else {
				gzwrite($file, $content);
			}
			return gzclose($file);
		}
		
		public function tulisSitemap() {
			if (!isset($this->dataSitemap))
				throw new Exception("Untuk membuat sitemap, Panggil fungsi buatSitemap terlebih dahulu.");
			if (isset($this->namaindexSitemap)) {
				$this->_tulisFile($this->namaindexSitemap[1], $this->pathDir, $this->namaindexSitemap[0]);
				foreach($this->dataSitemap as $sitemap) {
					$this->_tulisFile($sitemap[1], $this->pathDir, $sitemap[0]);
				}
			} else {
				$this->_tulisFile($this->dataSitemap[0][1], $this->pathDir, $this->dataSitemap[0][0]);
				if ($this->buatKompresiFile)
					$this->_tulisGZipFile($this->dataSitemap[0][1], $this->pathDir, $this->dataSitemap[0][0].".gz");
			}
		}

		public function ubahRobots() {
			if (!isset($this->dataSitemap))
				throw new Exception("Untuk mengubah robots.txt, Panggil fungsi buatSitemap terlebih dahulu.");
			$contohFileRobots = "User-agent: *\nAllow: /";
			if (file_exists($this->basePath.$this->namaFileRobot)) {
				$robotsFile = explode("\n", file_get_contents($this->pathDir.$this->namaFileRobot));
				$robotsFileContent = "";
				foreach($robotsFile as $key=>$value) {
					if(substr($value, 0, 8) == 'Sitemap:') unset($robotsFile[$key]);
					else $robotsFileContent .= $value."\n";
				}
				$robotsFileContent .= "Sitemap: ".$this->URlFullSitemap;
				if ($this->buatKompresiFile && !isset($this->namaindexSitemap))
					$robotsFileContent .= "\nSitemap: ".$this->URlFullSitemap.".gz";
				file_put_contents($this->pathDir.$this->namaFileRobot,$robotsFileContent);
			}
			else {
				$contohFileRobots = $contohFileRobots."\n\nSitemap: ".$this->URlFullSitemap;
				if ($this->buatKompresiFile && !isset($this->namaindexSitemap))
					$contohFileRobots .= "\nSitemap: ".$this->URlFullSitemap.".gz";
				file_put_contents($this->pathDir.$this->namaFileRobot, $contohFileRobots);
			}
		}
		
		public function kirimSitemap($IdAppYahoo = null) {
			if (!isset($this->dataSitemap))
				throw new Exception("Untuk Mengirim sitemap, Panggil fungsi buatSitemap terlebih dahulu.");
			if (!extension_loaded('curl'))
				throw new Exception("Librari cURL diperlukan. Check Server anda terlebih dahulu.");
			$kirimKeSE = $this->kirimKeSE;
			$kirimKeSE[0] = isset($IdAppYahoo) ? str_replace("IDAPPYAHOO", $IdAppYahoo, $kirimKeSE[0][0]) : $kirimKeSE[0][1];
			$hasil = array();
			for($i=0;$i<sizeof($kirimKeSE);$i++) {
				$kirimSite = curl_init($kirimKeSE[$i].htmlspecialchars($this->URlFullSitemap,ENT_QUOTES,'UTF-8'));
				curl_setopt($kirimSite, CURLOPT_RETURNTRANSFER, true);
				$infoContent = curl_exec($kirimSite);
				$info = curl_getinfo($kirimSite);
				$kirimSitePendek = array_reverse(explode(".",parse_url($kirimKeSE[$i], PHP_URL_HOST)));
				$hasil[] = array("site"=>$kirimSitePendek[1].".".$kirimSitePendek[0],
					"fullsite"=>$kirimKeSE[$i].htmlspecialchars($this->URlFullSitemap, ENT_QUOTES,'UTF-8'),
					"http_code"=>$info['http_code'],
					"message"=>str_replace("\n", " ", strip_tags($infoContent)));
			}
			return $hasil;
		}

	}
?>